<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='Ext-form-Labelable'>/**
</span> * A mixin which allows a component to be configured and decorated with a label and/or error message as is
 * common for form fields. This is used by e.g. Ext.form.field.Base and Ext.form.FieldContainer
 * to let them be managed by the Field layout.
 *
 * NOTE: This mixin is mainly for internal library use and most users should not need to use it directly. It
 * is more likely you will want to use one of the component classes that import this mixin, such as
 * Ext.form.field.Base or Ext.form.FieldContainer.
 *
 * Use of this mixin does not make a component a field in the logical sense, meaning it does not provide any
 * logic or state related to values or validation; that is handled by the related Ext.form.field.Field
 * mixin. These two mixins may be used separately (for example Ext.form.FieldContainer is Labelable but not a
 * Field), or in combination (for example Ext.form.field.Base implements both and has logic for connecting the
 * two.)
 *
 * Component classes which use this mixin should use the Field layout
 * or a derivation thereof to properly size and position the label and message according to the component config.
 * They must also call the {@link #initLabelable} method during component initialization to ensure the mixin gets
 * set up correctly.
 *
 * @docauthor Jason Johnston &lt;jason@sencha.com&gt;
 */
Ext.define(&quot;Ext.form.Labelable&quot;, {
    requires: ['Ext.XTemplate'],

    autoEl: {
        tag: 'table',
        cellpadding: 0
    },

    childEls: [
<span id='Ext-form-Labelable-property-labelCell'>        /**
</span>         * @property {Ext.Element} labelCell
         * The `&lt;TD&gt;` Element which contains the label Element for this component. Only available after the component has been rendered.
         */
        'labelCell',

<span id='Ext-form-Labelable-property-labelEl'>        /**
</span>         * @property {Ext.Element} labelEl
         * The label Element for this component. Only available after the component has been rendered.
         */
        'labelEl',

<span id='Ext-form-Labelable-property-bodyEl'>        /**
</span>         * @property {Ext.Element} bodyEl
         * The div Element wrapping the component's contents. Only available after the component has been rendered.
         */
        'bodyEl',

<span id='Ext-form-Labelable-property-errorEl'>        /**
</span>         * @property {Ext.Element} errorEl
         * The div Element that will contain the component's error message(s). Note that depending on the configured
         * {@link #msgTarget}, this element may be hidden in favor of some other form of presentation, but will always
         * be present in the DOM for use by assistive technologies.
         */
        'errorEl',

        'inputRow'
    ],

<span id='Ext-form-Labelable-cfg-labelableRenderTpl'>    /**
</span>     * @cfg {String/String[]/Ext.XTemplate} labelableRenderTpl
     * The rendering template for the field decorations. Component classes using this mixin
     * should include logic to use this as their {@link Ext.AbstractComponent#renderTpl renderTpl},
     * and implement the {@link #getSubTplMarkup} method to generate the field body content.
     *
     * The structure of a field is a table as follows:
     * 
     * If `label:align: 'left|top'`:
     *
     *      +----------------------+------------+---------+--------------+
     *      | Label:               | InputField           | sideErrorEl |
     *      +----------------------+------------+---------+-------------+
     *      |                      | underErrorEl (colspan=3)           |
     *      +-----------------------------------------------------------+
     *
     * Or, if `labelAlign: 'top'`:
     *
     *      +-----------------------------------------------------------+
     *      | labelAlign:'top' label: (colspan=3)                       |
     *      +----------------------+------------+---------+-------------+
     *      | InputField (colspan=2)                      | sideErrorEl |
     *      +----------------------+------------+---------+-------------+
     *      | underErrorEl (colspan=3)                                  |
     *      +-----------------------------------------------------------+
     *
     * The total columns always adds up to 3 (even if `labelAlign: 'top'`) because when
     * rendered into a {@link Ext.layout.container.Form} layout, just the `TR` of the table
     * will be placed into the form's main `TABLE`, and the columns of all the siblings
     * must match so that they all line up.
     *
     * When the triggerCell or side error cell are hidden or shown, the input cell's colspan
     * is recalculated to maintain the correct 3 visible column count.
     * @private
     */
    labelableRenderTpl: [

        // Top TR if labelAlign =='top'
        '&lt;tpl if=&quot;labelAlign==\'top\'&quot;&gt;',
            '&lt;tr&gt;',
                '&lt;td id=&quot;{id}-labelCell&quot; colspan=&quot;3&quot; style=&quot;{labelCellStyle}&quot; {labelCellAttrs}&gt;',
                    '{beforeLabelTpl}',
                    '&lt;label id=&quot;{id}-labelEl&quot; {labelAttrTpl}&lt;tpl if=&quot;inputId&quot;&gt; for=&quot;{inputId}&quot;&lt;/tpl&gt; class=&quot;{labelCls}&quot;',
                        '&lt;tpl if=&quot;labelStyle&quot;&gt; style=&quot;{labelStyle}&quot;&lt;/tpl&gt;&gt;',
                        '{beforeLabelTextTpl}',
                        '&lt;tpl if=&quot;fieldLabel&quot;&gt;{fieldLabel}{labelSeparator}&lt;/tpl&gt;',
                        '{afterLabelTextTpl}',
                    '&lt;/label&gt;',
                    '{afterLabelTpl}',
                '&lt;/td&gt;',
            '&lt;/tr&gt;',
        '&lt;/tpl&gt;',

        // body row. If a heighted Field (eg TextArea, HtmlEditor, this must greedily consume height.
        '&lt;tr id=&quot;{id}-inputRow&quot; &lt;tpl if=&quot;inFormLayout&quot;&gt;id=&quot;{id}&quot;&lt;/tpl&gt;&gt;',

            // Label cell
            '&lt;tpl if=&quot;labelOnLeft&quot;&gt;',
                '&lt;td id=&quot;{id}-labelCell&quot; style=&quot;{labelCellStyle}&quot; {labelCellAttrs}&gt;',
                    '{beforeLabelTpl}',
                    '&lt;label id=&quot;{id}-labelEl&quot; {labelAttrTpl}&lt;tpl if=&quot;inputId&quot;&gt; for=&quot;{inputId}&quot;&lt;/tpl&gt; class=&quot;{labelCls}&quot;',
                        '&lt;tpl if=&quot;labelStyle&quot;&gt; style=&quot;{labelStyle}&quot;&lt;/tpl&gt;&gt;',
                        '{beforeLabelTextTpl}',
                        '&lt;tpl if=&quot;fieldLabel&quot;&gt;{fieldLabel}{labelSeparator}&lt;/tpl&gt;',
                        '{afterLabelTextTpl}',
                    '&lt;/label&gt;',
                    '{afterLabelTpl}',
                '&lt;/td&gt;',
            '&lt;/tpl&gt;',

            // Body of the input. That will be an input element, or, from a TriggerField, a table containing an input cell and trigger cell(s)
            '&lt;td class=&quot;{baseBodyCls} {fieldBodyCls}&quot; id=&quot;{id}-bodyEl&quot; role=&quot;presentation&quot; colspan=&quot;{bodyColspan}&quot;&gt;',
                '{beforeSubTpl}',
                '{[values.$comp.getSubTplMarkup()]}',
                '{afterSubTpl}',
            '&lt;/td&gt;',

            // Side error element
            '&lt;tpl if=&quot;msgTarget==\'side\'&quot;&gt;',
                '&lt;td id=&quot;{id}-errorEl&quot; class=&quot;{errorMsgCls}&quot; style=&quot;display:none&quot; width=&quot;{errorIconWidth}&quot;&gt;&lt;/td&gt;',
            '&lt;/tpl&gt;',
        '&lt;/tr&gt;',

        // Under error element is another TR
        '&lt;tpl if=&quot;msgTarget==\'under\'&quot;&gt;',
            '&lt;tr&gt;',
                // Align under the input element
                '&lt;tpl if=&quot;labelOnLeft&quot;&gt;',
                    '&lt;td&gt;&lt;/td&gt;',
                '&lt;/tpl&gt;',
                '&lt;td id=&quot;{id}-errorEl&quot; class=&quot;{errorMsgClass}&quot; colspan=&quot;{[values.labelOnLeft ? 2 : 3]}&quot; style=&quot;display:none&quot;&gt;&lt;/td&gt;',
            '&lt;/tr&gt;',
        '&lt;/tpl&gt;',
        {
            disableFormats: true
        }
    ],

<span id='Ext-form-Labelable-cfg-activeErrorsTpl'>    /**
</span>     * @cfg {String/String[]/Ext.XTemplate} activeErrorsTpl
     * The template used to format the Array of error messages passed to {@link #setActiveErrors} into a single HTML
     * string. By default this renders each message as an item in an unordered list.
     */
    activeErrorsTpl: [
        '&lt;tpl if=&quot;errors &amp;&amp; errors.length&quot;&gt;',
            '&lt;ul&gt;&lt;tpl for=&quot;errors&quot;&gt;&lt;li&gt;{.}&lt;/li&gt;&lt;/tpl&gt;&lt;/ul&gt;',
        '&lt;/tpl&gt;'
    ],

<span id='Ext-form-Labelable-property-isFieldLabelable'>    /**
</span>     * @property {Boolean} isFieldLabelable
     * Flag denoting that this object is labelable as a field. Always true.
     */
    isFieldLabelable: true,

<span id='Ext-form-Labelable-cfg-formItemCls'>    /**
</span>     * @cfg {String} formItemCls
     * A CSS class to be applied to the outermost element to denote that it is participating in the form field layout.
     */
    formItemCls: Ext.baseCSSPrefix + 'form-item',

<span id='Ext-form-Labelable-cfg-labelCls'>    /**
</span>     * @cfg {String} labelCls
     * The CSS class to be applied to the label element. This (single) CSS class is used to formulate the renderSelector
     * and drives the field layout where it is concatenated with a hyphen ('-') and {@link #labelAlign}. To add
     * additional classes, use {@link #labelClsExtra}.
     */
    labelCls: Ext.baseCSSPrefix + 'form-item-label',

<span id='Ext-form-Labelable-cfg-labelClsExtra'>    /**
</span>     * @cfg {String} labelClsExtra
     * An optional string of one or more additional CSS classes to add to the label element. Defaults to empty.
     */

<span id='Ext-form-Labelable-cfg-errorMsgCls'>    /**
</span>     * @cfg {String} errorMsgCls
     * The CSS class to be applied to the error message element.
     */
    errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg',

<span id='Ext-form-Labelable-cfg-baseBodyCls'>    /**
</span>     * @cfg {String} baseBodyCls
     * The CSS class to be applied to the body content element.
     */
    baseBodyCls: Ext.baseCSSPrefix + 'form-item-body',

<span id='Ext-form-Labelable-cfg-fieldBodyCls'>    /**
</span>     * @cfg {String} fieldBodyCls
     * An extra CSS class to be applied to the body content element in addition to {@link #baseBodyCls}.
     */
    fieldBodyCls: '',

<span id='Ext-form-Labelable-cfg-clearCls'>    /**
</span>     * @cfg {String} clearCls
     * The CSS class to be applied to the special clearing div rendered directly after the field contents wrapper to
     * provide field clearing.
     */
    clearCls: Ext.baseCSSPrefix + 'clear',

<span id='Ext-form-Labelable-cfg-invalidCls'>    /**
</span>     * @cfg {String} invalidCls
     * The CSS class to use when marking the component invalid.
     */
    invalidCls : Ext.baseCSSPrefix + 'form-invalid',

<span id='Ext-form-Labelable-cfg-fieldLabel'>    /**
</span>     * @cfg {String} fieldLabel
     * The label for the field. It gets appended with the {@link #labelSeparator}, and its position and sizing is
     * determined by the {@link #labelAlign}, {@link #labelWidth}, and {@link #labelPad} configs.
     */
    fieldLabel: undefined,

<span id='Ext-form-Labelable-cfg-labelAlign'>    /**
</span>     * @cfg {String} labelAlign
     * Controls the position and alignment of the {@link #fieldLabel}. Valid values are:
     *
     *   - &quot;left&quot; (the default) - The label is positioned to the left of the field, with its text aligned to the left.
     *     Its width is determined by the {@link #labelWidth} config.
     *   - &quot;top&quot; - The label is positioned above the field.
     *   - &quot;right&quot; - The label is positioned to the left of the field, with its text aligned to the right.
     *     Its width is determined by the {@link #labelWidth} config.
     */
    labelAlign : 'left',

<span id='Ext-form-Labelable-cfg-labelWidth'>    /**
</span>     * @cfg {Number} labelWidth
     * The width of the {@link #fieldLabel} in pixels. Only applicable if the {@link #labelAlign} is set to &quot;left&quot; or
     * &quot;right&quot;.
     */
    labelWidth: 100,

<span id='Ext-form-Labelable-cfg-labelPad'>    /**
</span>     * @cfg {Number} labelPad
     * The amount of space in pixels between the {@link #fieldLabel} and the input field.
     */
    labelPad : 5,

<span id='Ext-form-Labelable-cfg-labelSeparator'>    /**
</span>     * @cfg {String} labelSeparator
     * Character(s) to be inserted at the end of the {@link #fieldLabel label text}.
     */
    //&lt;locale&gt;
    labelSeparator : ':',
    //&lt;/locale&gt;

<span id='Ext-form-Labelable-cfg-labelStyle'>    /**
</span>     * @cfg {String} labelStyle
     * A CSS style specification string to apply directly to this field's label.
     */

<span id='Ext-form-Labelable-cfg-hideLabel'>    /**
</span>     * @cfg {Boolean} hideLabel
     * Set to true to completely hide the label element ({@link #fieldLabel} and {@link #labelSeparator}). Also see
     * {@link #hideEmptyLabel}, which controls whether space will be reserved for an empty fieldLabel.
     */
    hideLabel: false,

<span id='Ext-form-Labelable-cfg-hideEmptyLabel'>    /**
</span>     * @cfg {Boolean} hideEmptyLabel
     * When set to true, the label element ({@link #fieldLabel} and {@link #labelSeparator}) will be automatically
     * hidden if the {@link #fieldLabel} is empty. Setting this to false will cause the empty label element to be
     * rendered and space to be reserved for it; this is useful if you want a field without a label to line up with
     * other labeled fields in the same form.
     *
     * If you wish to unconditionall hide the label even if a non-empty fieldLabel is configured, then set the {@link
     * #hideLabel} config to true.
     */
    hideEmptyLabel: true,

<span id='Ext-form-Labelable-cfg-preventMark'>    /**
</span>     * @cfg {Boolean} preventMark
     * true to disable displaying any {@link #setActiveError error message} set on this object.
     */
    preventMark: false,

<span id='Ext-form-Labelable-cfg-autoFitErrors'>    /**
</span>     * @cfg {Boolean} autoFitErrors
     * Whether to adjust the component's body area to make room for 'side' or 'under' {@link #msgTarget error messages}.
     */
    autoFitErrors: true,

<span id='Ext-form-Labelable-cfg-msgTarget'>    /**
</span>     * @cfg {String} msgTarget
     * The location where the error message text should display. Must be one of the following values:
     *
     *   - `qtip` Display a quick tip containing the message when the user hovers over the field.
     *     This is the default.
     *
     *     **{@link Ext.tip.QuickTipManager#init} must have been called for this setting to work.**
     *
     *   - `title` Display the message in a default browser title attribute popup.
     *   - `under` Add a block div beneath the field containing the error message.
     *   - `side` Add an error icon to the right of the field, displaying the message in a popup on hover.
     *   - `none` Don't display any error message. This might be useful if you are implementing custom error display.
     *   - `[element id]` Add the error message directly to the innerHTML of the specified element.
     */
    msgTarget: 'qtip',

<span id='Ext-form-Labelable-cfg-activeError'>    /**
</span>     * @cfg {String} activeError
     * If specified, then the component will be displayed with this value as its active error when first rendered. Use
     * {@link #setActiveError} or {@link #unsetActiveError} to change it after component creation.
     */

<span id='Ext-form-Labelable-property-noWrap'>    /**
</span>     * @private
     * Tells the layout system that the height can be measured immediately because the width does not need setting.
     */
    noWrap: true,

    labelableInsertions: [
<span id='Ext-form-Labelable-cfg-beforeLabelTpl'>        /**
</span>         * @cfg {String/Array/Ext.XTemplate} beforeLabelTpl
         * An optional string or `XTemplate` configuration to insert in the field markup
         * before the label element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
         * serves as the context.
         */
        'beforeLabelTpl',

<span id='Ext-form-Labelable-cfg-afterLabelTpl'>        /**
</span>         * @cfg {String/Array/Ext.XTemplate} afterLabelTpl
         * An optional string or `XTemplate` configuration to insert in the field markup
         * after the label element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
         * serves as the context.
         */
        'afterLabelTpl',

<span id='Ext-form-Labelable-cfg-beforeSubTpl'>        /**
</span>         * @cfg {String/Array/Ext.XTemplate} beforeSubTpl
         * An optional string or `XTemplate` configuration to insert in the field markup
         * before the {@link #getSubTplMarkup subTpl markup}. If an `XTemplate` is used, the
         * component's {@link Ext.AbstractComponent#renderData render data} serves as the context.
         */
        'beforeSubTpl',

<span id='Ext-form-Labelable-cfg-afterSubTpl'>        /**
</span>         * @cfg {String/Array/Ext.XTemplate} afterSubTpl
         * An optional string or `XTemplate` configuration to insert in the field markup
         * after the {@link #getSubTplMarkup subTpl markup}. If an `XTemplate` is used, the
         * component's {@link Ext.AbstractComponent#renderData render data} serves as the context.
         */
        'afterSubTpl',

<span id='Ext-form-Labelable-cfg-beforeLabelTextTpl'>        /**
</span>         * @cfg {String/Array/Ext.XTemplate} beforeLabelTextTpl
         * An optional string or `XTemplate` configuration to insert in the field markup
         * before the label text. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
         * serves as the context.
         */
        'beforeLabelTextTpl',

<span id='Ext-form-Labelable-cfg-afterLabelTextTpl'>        /**
</span>         * @cfg {String/Array/Ext.XTemplate} afterLabelTextTpl
         * An optional string or `XTemplate` configuration to insert in the field markup
         * after the label text. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
         * serves as the context.
         */
        'afterLabelTextTpl',

<span id='Ext-form-Labelable-cfg-labelAttrTpl'>        /**
</span>         * @cfg {String/Array/Ext.XTemplate} labelAttrTpl
         * An optional string or `XTemplate` configuration to insert in the field markup
         * inside the label element (as attributes). If an `XTemplate` is used, the component's
         * {@link Ext.AbstractComponent#renderData render data} serves as the context.
         */
        'labelAttrTpl'
    ],

    labelableRenderProps: 'allowBlank,labelAlign,fieldBodyCls,baseBodyCls,clearCls,labelSeparator,msgTarget',

<span id='Ext-form-Labelable-method-initLabelable'>    /**
</span>     * Performs initialization of this mixin. Component classes using this mixin should call this method during their
     * own initialization.
     */
    initLabelable: function() {
        var me = this,
            padding = me.padding;

        // This Component is rendered as a table. Padding doesn't work on tables
        // Before padding can be applied to the encapsulating table element, copy the padding into
        // an extraMargins property which is to be added to all computed margins post render :(
        if (padding) {
            me.padding = undefined;
            me.extraMargins = Ext.Element.parseBox(padding);
        }

        me.addCls(me.formItemCls);
        
        // Prevent first render of active error, at Field render time from signalling a change from undefined to &quot;
        me.lastActiveError = '';

        me.addEvents(
<span id='Ext-form-Labelable-event-errorchange'>            /**
</span>             * @event errorchange
             * Fires when the active error message is changed via {@link #setActiveError}.
             * @param {Ext.form.Labelable} this
             * @param {String} error The active error message
             */
            'errorchange'
        );
    },

<span id='Ext-form-Labelable-method-getFieldLabel'>    /**
</span>     * Returns the label for the field. Defaults to simply returning the {@link #fieldLabel} config. Can be overridden
     * to provide
     * @return {String} The configured field label, or empty string if not defined
     */
    getFieldLabel: function() {
        return this.fieldLabel || '';
    },
    
<span id='Ext-form-Labelable-method-setFieldLabel'>    /**
</span>     * Set the label of this field.
     * @param {String} label The new label. The {@link #labelSeparator} will be automatically appended to the label
     * string.
     */
    setFieldLabel: function(label){
        label = label || '';
        
        var me = this,
            separator = me.labelSeparator,
            labelEl = me.labelEl,
            last;
        
        me.fieldLabel = label;
        if (me.rendered) {
            if (Ext.isEmpty(label) &amp;&amp; me.hideEmptyLabel) {
                labelEl.parent().setDisplayed('none');
            } else {
                if (separator) {
                    last = label.substr(label.length - 1);
                    // append separator if necessary
                    if (last != separator) {
                        label += separator;
                    }
                }
                labelEl.update(label);
                labelEl.parent().setDisplayed('');
            }
            me.updateLayout();
        }
    },

    getInsertionRenderData: function (data, names) {
        var i = names.length,
            name, value;

        while (i--) {
            name = names[i];
            value = this[name];

            if (value) {
                if (typeof value != 'string') {
                    if (!value.isTemplate) {
                        value = Ext.XTemplate.getTpl(this, name);
                    }
                    value = value.apply(data);
                }
            }

            data[name] = value || '';
        }

        return data;
    },

<span id='Ext-form-Labelable-method-getLabelableRenderData'>    /**
</span>     * Generates the arguments for the field decorations {@link #labelableRenderTpl rendering template}.
     * @return {Object} The template arguments
     * @protected
     */
    getLabelableRenderData: function() {
        var me = this,
            data,
            tempEl;

        if (!Ext.form.Labelable.errorIconWidth) {
            Ext.form.Labelable.errorIconWidth = (tempEl = Ext.getBody().createChild({style: 'position:absolute', cls: Ext.baseCSSPrefix + 'form-invalid-icon'})).getWidth();
            tempEl.remove();
        }

        data = Ext.copyTo({
            inFormLayout   : me.ownerLayout &amp;&amp; me.ownerLayout.type === 'form',
            inputId        : me.getInputId(),
            labelOnLeft    : me.labelAlign != 'top',
            fieldLabel     : me.getFieldLabel(),
            labelCellStyle : me.getLabelCellStyle(),
            labelCellAttrs : me.getLabelCellAttrs(),
            labelCls       : me.getLabelCls(),
            labelStyle     : me.getLabelStyle(),
            bodyColspan    : me.getBodyColspan(),
            errorMsgCls    : me.errorMsgCls + (me.autoFitErrors ? '' : ' ' + Ext.baseCSSPrefix + 'external-error-icon'),
            errorIconWidth : Ext.form.Labelable.errorIconWidth
        },
        me, me.labelableRenderProps, true);

        me.getInsertionRenderData(data, me.labelableInsertions);

        return data;
    },
    
    beforeLabelableRender: function() {
        var me = this;
        if (me.ownerLayout) {
            me.addCls(Ext.baseCSSPrefix + me.ownerLayout.type + '-form-item');
        }
    },

    onLabelableRender: function() {
        var me = this,
            margins,
            side,
            style = {};

        if (me.extraMargins) {
            margins = me.el.getMargin();
            for (side in margins) {
                if (margins.hasOwnProperty(side)) {
                    style['margin-' + side] = (margins[side] + me.extraMargins[side]) + 'px';
                }
            }
            me.el.setStyle(style);
        }
    },
    
<span id='Ext-form-Labelable-method-hasVisibleLabel'>    /**
</span>     * Checks if the field has a visible label
     * @return {Boolean} True if the field has a visible label
     */
    hasVisibleLabel: function(){
        if (this.hideLabel) {
            return false;
        }
        return !(this.hideEmptyLabel &amp;&amp; !this.getFieldLabel());
    },

<span id='Ext-form-Labelable-method-getBodyColspan'>    /**
</span>     * @private
     * Calculates the colspan value for the body cell - the cell which contains the input field.
     *
     * The field table structure contains 4 columns:
     */
    getBodyColspan: function() {
        var me = this,
            hideLabelCell = !me.hasVisibleLabel(),
            result;

            // In the base case, the body cell spans itself, the triggerWrap cell, and the sideErrorEl by default, so 3
            // If the label cell is hidden, or on the row above, the body cell must span the left label cell too, so 4
            // TriggerFields which show the trigger cell, decrement this in the subclass implementation.
            result = (hideLabelCell || me.labelAlign === 'top') ? 3 : 2;

            if (me.hasActiveError()) {
                result--;
            }

            return result;
    },
    
    getLabelCls: function(){
        var labelCls = this.labelCls,
            labelClsExtra = this.labelClsExtra;
            
        return labelClsExtra ? labelCls + ' ' + labelClsExtra : labelCls;
    },

    getLabelCellStyle: function() {
        var me = this,
            hideLabelCell = me.hideLabel || (!me.fieldLabel &amp;&amp; me.hideEmptyLabel);

        return hideLabelCell ? 'display:none;' : '';
    },

    getLabelCellAttrs: function() {
        var me = this,
            labelAlign = me.labelAlign,
            result = '';

        if (labelAlign !== 'top') {
            result = 'valign=&quot;top&quot; halign=&quot;' + labelAlign + '&quot; width=&quot;' + (me.labelWidth + me.labelPad) + '&quot;';
        }
        return result + ' class=&quot;' + Ext.baseCSSPrefix + 'field-label-cell&quot;';
    },
    
<span id='Ext-form-Labelable-method-getLabelStyle'>    /**
</span>     * Gets any label styling for the labelEl
     * @private
     * @return {String} The label styling
     */
    getLabelStyle: function(){
        var me = this,
            labelPad = me.labelPad,
            labelStyle = '';

        // Calculate label styles up front rather than in the Field layout for speed; this
        // is safe because label alignment/width/pad are not expected to change.
        if (me.labelAlign === 'top') {
            labelStyle = 'margin-bottom:' + labelPad + 'px;';
        } else {
            if (me.labelWidth) {
                labelStyle = 'width:' + me.labelWidth + 'px;';
            }
            labelStyle += 'margin-right:' + labelPad + 'px;';
        }
        
        return labelStyle + (me.labelStyle || '');
    },

<span id='Ext-form-Labelable-method-getSubTplMarkup'>    /**
</span>     * Gets the markup to be inserted into the outer template's bodyEl. Defaults to empty string, should be implemented
     * by classes including this mixin as needed.
     * @return {String} The markup to be inserted
     * @protected
     */
    getSubTplMarkup: function() {
        return '';
    },

<span id='Ext-form-Labelable-method-getInputId'>    /**
</span>     * Get the input id, if any, for this component. This is used as the &quot;for&quot; attribute on the label element.
     * Implementing subclasses may also use this as e.g. the id for their own input element.
     * @return {String} The input id
     */
    getInputId: function() {
        return '';
    },

<span id='Ext-form-Labelable-method-getActiveError'>    /**
</span>     * Gets the active error message for this component, if any. This does not trigger validation on its own, it merely
     * returns any message that the component may already hold.
     * @return {String} The active error message on the component; if there is no error, an empty string is returned.
     */
    getActiveError : function() {
        return this.activeError || '';
    },

<span id='Ext-form-Labelable-method-hasActiveError'>    /**
</span>     * Tells whether the field currently has an active error message. This does not trigger validation on its own, it
     * merely looks for any message that the component may already hold.
     * @return {Boolean}
     */
    hasActiveError: function() {
        return !!this.getActiveError();
    },

<span id='Ext-form-Labelable-method-setActiveError'>    /**
</span>     * Sets the active error message to the given string. This replaces the entire error message contents with the given
     * string. Also see {@link #setActiveErrors} which accepts an Array of messages and formats them according to the
     * {@link #activeErrorsTpl}. Note that this only updates the error message element's text and attributes, you'll
     * have to call doComponentLayout to actually update the field's layout to match. If the field extends {@link
     * Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
     * @param {String} msg The error message
     */
    setActiveError: function(msg) {
        this.setActiveErrors(msg);
    },

<span id='Ext-form-Labelable-method-getActiveErrors'>    /**
</span>     * Gets an Array of any active error messages currently applied to the field. This does not trigger validation on
     * its own, it merely returns any messages that the component may already hold.
     * @return {String[]} The active error messages on the component; if there are no errors, an empty Array is
     * returned.
     */
    getActiveErrors: function() {
        return this.activeErrors || [];
    },

<span id='Ext-form-Labelable-method-setActiveErrors'>    /**
</span>     * Set the active error message to an Array of error messages. The messages are formatted into a single message
     * string using the {@link #activeErrorsTpl}. Also see {@link #setActiveError} which allows setting the entire error
     * contents with a single string. Note that this only updates the error message element's text and attributes,
     * you'll have to call doComponentLayout to actually update the field's layout to match. If the field extends
     * {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
     * @param {String[]} errors The error messages
     */
    setActiveErrors: function(errors) {
        errors = Ext.Array.from(errors);
        this.activeError = errors[0];
        this.activeErrors = errors;
        this.activeError = this.getTpl('activeErrorsTpl').apply({errors: errors});
        this.renderActiveError();
    },

<span id='Ext-form-Labelable-method-unsetActiveError'>    /**
</span>     * Clears the active error message(s). Note that this only clears the error message element's text and attributes,
     * you'll have to call doComponentLayout to actually update the field's layout to match. If the field extends {@link
     * Ext.form.field.Base} you should call {@link Ext.form.field.Base#clearInvalid clearInvalid} instead.
     */
    unsetActiveError: function() {
        delete this.activeError;
        delete this.activeErrors;
        this.renderActiveError();
    },

<span id='Ext-form-Labelable-method-renderActiveError'>    /**
</span>     * @private
     * Updates the rendered DOM to match the current activeError. This only updates the content and
     * attributes, you'll have to call doComponentLayout to actually update the display.
     */
    renderActiveError: function() {
        var me = this,
            activeError = me.getActiveError(),
            hasError = !!activeError;

        if (activeError !== me.lastActiveError) {
            me.fireEvent('errorchange', me, activeError);
            me.lastActiveError = activeError;
        }

        if (me.rendered &amp;&amp; !me.isDestroyed &amp;&amp; !me.preventMark) {
            // Add/remove invalid class
            me.el[hasError ? 'addCls' : 'removeCls'](me.invalidCls);

            // Update the aria-invalid attribute
            me.getActionEl().dom.setAttribute('aria-invalid', hasError);

            // Update the errorEl (There will only be one if msgTarget is 'side' or 'under') with the error message text
            if (me.errorEl) {
                me.errorEl.dom.innerHTML = activeError;
            }
        }
    },

<span id='Ext-form-Labelable-method-setFieldDefaults'>    /**
</span>     * Applies a set of default configuration values to this Labelable instance. For each of the properties in the given
     * object, check if this component hasOwnProperty that config; if not then it's inheriting a default value from its
     * prototype and we should apply the default value.
     * @param {Object} defaults The defaults to apply to the object.
     */
    setFieldDefaults: function(defaults) {
        var me = this,
            val, key;

        for (key in defaults) {
            if (defaults.hasOwnProperty(key)) {
                val = defaults[key];

                if (!me.hasOwnProperty(key)) {
                    me[key] = val;
                }
            }
        }
    }
});
</pre>
</body>
</html>
